package com.psedu.base.service.impl;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.psedu.base.constant.Constants;
import com.psedu.base.constant.ResponseConstants;
import com.psedu.base.domain.Semester;
import com.psedu.base.domain.vo.ApplyVo;
import com.psedu.base.domain.vo.SimpleUserApplyVo;
import com.psedu.base.mapper.SemesterMapper;
import com.psedu.common.core.constant.HttpStatus;
import com.psedu.common.core.exception.ServiceException;
import com.psedu.common.mybatis.core.page.PageQuery;
import com.psedu.common.mybatis.core.page.TableDataInfo;
import com.psedu.common.security.utils.SecurityUtils;
import com.psedu.system.api.model.LoginUser;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.psedu.base.mapper.ApplyMapper;
import com.psedu.base.domain.Apply;
import com.psedu.base.service.IApplyService;

/**
 * 培训报名Service业务层处理
 * 
 * @author mingyue
 * @date 2022-01-31
 */
@Service
public class ApplyServiceImpl implements IApplyService 
{
    @Autowired
    private ApplyMapper applyMapper;

    @Autowired
    private SemesterMapper semesterMapper;

    /**
     * 查询培训报名
     * 
     * @param applyId 培训报名主键
     * @return 培训报名
     */
    @Override
    public Apply selectApplyByApplyId(Long applyId)
    {
        return applyMapper.selectById(applyId);
    }

//    @Override
//    public TableDataInfo<Apply> selectApplyList(PageQuery pageQuery, Apply apply) {
//        return applyMapper.selectApplyList(pageQuery, apply);
//    }

//    /**
//     * 查询培训报名列表
//     *
//     * @param apply 培训报名
//     * @return 培训报名
//     */
//    @Override
//    public List<Apply> selectApplyList(Apply apply)
//    {
//        return applyMapper.selectApplyList(apply);
//    }

    /**
     * 新增培训报名
     * 
     * @param apply 培训报名
     * @return 结果
     */
    @Override
    public int insertApply(Apply apply)
    {
        return applyMapper.insert(apply);
    }

    /**
     * 修改培训报名
     * 
     * @param apply 培训报名
     * @return 结果
     */
    @Override
    public int updateApply(Apply apply)
    {
        return applyMapper.updateById(apply);
    }

    /**
     * 批量删除培训报名
     * 
     * @param applyIds 需要删除的培训报名主键
     * @return 结果
     */
    @Override
    public int deleteApplyByApplyIds(Long[] applyIds)
    {
        return applyMapper.deleteBatchIds(Arrays.asList(applyIds));
    }

    /**
     * 删除培训报名信息
     * 
     * @param applyId 培训报名主键
     * @return 结果
     */
    @Override
    public int deleteApplyByApplyId(Long applyId)
    {
        return applyMapper.deleteById(applyId);
    }

    @Override
    public TableDataInfo<Apply> selectApplyList(PageQuery pageQuery, Apply apply) {
        Page<Apply> page = applyMapper.selectApplyList(pageQuery.build(), apply);
        return TableDataInfo.build(page);
    }

    @Override
    public List<Apply> testSelectList(Apply apply) {
        List<Apply>  list = applyMapper.testSelectList(apply);
        return list;
    }

    /**
     * 根据ID查用戶申请
     * @param userId 用户ID
     * @return 申请列表
     */
    @Override
    public List<SimpleUserApplyVo> userApply(Long userId) {
        System.out.println(userId);
        List<SimpleUserApplyVo> simpleUserApplyVos = applyMapper.userApplyList(userId);
        return simpleUserApplyVos;
    }

    @Override
    public String userApplySummary(Long userId, Long applyId) {
        Apply apply = applyMapper.selectOne(
                new LambdaQueryWrapper<Apply>()
                        .select(
                                Apply::getApplyId,
                                Apply::getSummary,
                                Apply::getPsUserId
                        )
                        .eq(Apply::getApplyId, applyId)
                        .orderByDesc(Apply::getApplyId)
        );
        // 不是本人
        if( apply!= null && !userId.equals(apply.getPsUserId()) ) {
            throw new ServiceException("没有权限访问用户数据！");
        }
        return apply != null ?
                ( apply.getSummary() == null ? "" : apply.getSummary() )
                : "";
    }

    @Override
    public int submitApply(ApplyVo applyVo) {
        assertAudlt(applyVo.getBirthday());
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userId = loginUser.getUserid();
        // 学期是否进行中
        assertSemesterActive(applyVo.getSemeId());
        Long applyId = applyVo.getApplyId();
        // 新增
        if(applyId == null) {
            Apply oldApply = applyMapper.selectOne(
                    new LambdaQueryWrapper<Apply>()
                        .eq(Apply::getPsUserId, userId)
                        .eq(Apply::getSemeId, applyVo.getSemeId())
            );
            if(oldApply != null) {
                throw new ServiceException("已存在申请，不可重复申请", HttpStatus.FORBIDDEN);
            }
            Apply newApply = new Apply();
            BeanUtils.copyProperties(applyVo, newApply);
            newApply.setChecked(0);
            newApply.setDeptId(loginUser.getDeptId());
            newApply.setPsUserId(userId);
            return applyMapper.insert(newApply);
        // 修改
        } else {
            Apply oldApply = applyMapper.selectById(applyId);
            if(Constants.APPLY_PASS == oldApply.getChecked()) {
                throw new ServiceException("审核通过，不可修改", HttpStatus.FORBIDDEN);
            }
            Apply newApply = new Apply();
            BeanUtils.copyProperties(applyVo, newApply);
            newApply.setChecked(0);
            return applyMapper.update(
                    newApply,
                    new LambdaUpdateWrapper<Apply>()
                        .eq(Apply::getPsUserId, userId)
                        .eq(Apply::getApplyId, applyId)
            );
        }
    }

    private void assertAudlt(Date birthday) {
        int age = DateUtil.ageOfNow(birthday);
        if(age < 18) {
            throw new ServiceException("年龄小于十八岁不可报名", ResponseConstants.FORBIDDEN);
        }
    }

    private void assertSemesterActive(Long semeId) {
        Semester semester = semesterMapper.selectOne(
                new LambdaQueryWrapper<Semester>()
                    .select(Semester::getSemeId, Semester::getActive)
                    .eq(Semester::getSemeId, semeId)
        );
        if(Constants.SEMESTER_INACTIVE == semester.getActive()) {
            throw new ServiceException("报名已经截止，不可新增/编辑报名信息");
        }
    }

    @Override
    public ApplyVo getApplyDetailByApplyId(Long applyId) {
        return applyMapper.selectVoById(applyId, ApplyVo.class);
    }

    @Override
    public int applyPass(Long applyId) {
        Apply apply = new Apply();
        apply.setApplyId(applyId);
        apply.setChecked(Constants.APPLY_PASS);
        return applyMapper.updateById(apply);
    }
}